#pragma once
#include <stdio.h>
#include <signal.h>
#include <atomic>
#include <string>
#include <thread>
#include <iostream>
#include <vector>
#include <mutex>
#include <queue>
#include <opencv2/opencv.hpp>

extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/imgutils.h>
#include <libavutil/timestamp.h>
#include <libswscale/swscale.h>
}
#include "base_pusher.h"

namespace stream {


class CUStreamPusher: public BasePusher
{
public:
  CUStreamPusher(StreamPusherInfo* spifo, LogInfo* log_info);
  ~CUStreamPusher();

public:
  int init_params();
  int start_push();
  int stop_push();
  int add_frame(stream::ImageBlob& buffer);


private:
  SwsContext* initialize_sample_scaler();
  AVFrame* allocate_frame_buffer();
  int write_frame(AVFrame *frame);

  void release_ffmpeg();

public: 


private:
  std::mutex queue_lock;
  std::queue<stream::ImageBlob> queue_data;
  int queue_data_pop_cnt;
  
  AVFormatContext *ofmt_ctx = nullptr;
  AVCodec *out_codec = nullptr;
  AVStream *out_stream = nullptr;
  AVCodecContext *out_codec_ctx = nullptr;


};


}   // namespace camera
